#ifndef STRATEGY_H
#define STRATEGY_H

#include "player.h"
#include "playhand.h"

/* 出牌策略类 */
class Strategy
{
public:
    // Strategy类的构造
    Strategy(Player* player, const Cards& cards);

    // 制定出牌的策略
    Cards makeStrategy();
    // 第一个出牌 firstPlay 给机器人玩家使用
    Cards firstPlay();
    // 得到比指定牌大的牌
    Cards getGreaterCards(PlayHand type);
    // 在有大过指定的牌时，判断是出牌还是放行，返回true ------> 出牌， 返回false ------> 放行
    bool whetherToBeat(Cards& cs);

    // 找到指定数量的相同点数的扑克牌，即找到count张点数为point的扑克牌 例如： 4个3
    Cards findSamePointCards(Card::CardPoint point, int count);
    
    // 找到数量(count)相同，点数不同的牌
    QVector<Cards> findCardsByCount(int count);
    
    // 根据点数的范围找到牌
    Cards getRangeCards(Card::CardPoint begin, Card::CardPoint end);
    
    // 按牌型找牌，并且指定要找到的牌是否大于指定牌的类型
    QVector<Cards> findCardType(PlayHand hand, bool beat);
    
    // 从指定的Cards对象中挑选出满足条件的顺子
    void pickSeqSingles(QVector<QVector<Cards>>& allSeqRecord, const QVector<Cards>& seqSingle, const Cards& cards);
    // 从集合中筛选最优解的顺子（即：顺子越长，玩家所出牌越多，手牌中的单牌越少，就越可能赢）
    QVector<Cards> pickOptimalSeqSingles(); // TODO: ??????

private:
    using fptr = Cards (Strategy::*)(Card::CardPoint point);
    struct CardInfo
    {
        Card::CardPoint begin;  // 起始点数
        Card::CardPoint end;    // 终止点数
        int extra;              // 顺子或连对的数量
        bool beat;              // 顺子或连对的点数是否与extra有关联
        int number;             // 指定的张数
        int base;               // 构成基础牌型的张数
        fptr getSeq;            // 肇东顺子或连对基础构成
    };

    // 找到指定点数的number张牌
    QVector<Cards> getCards(Card::CardPoint point, int number);
    // 找到3带1牌或2的牌
    QVector<Cards> getTripleSingleOrPair(Card::CardPoint begin, PlayHand::HandType type);
    // 找到多组飞机
    QVector<Cards> getPlane(Card::CardPoint begin);
    // 找到多组飞机带1或则2
    QVector<Cards> getPlane2SingleOr2Pair(Card::CardPoint begin, PlayHand::HandType type);
    // 找到连对或者顺子
    // QVector<Cards> getSepPairOrSeqSingle(Card::CardPoint begin, int extra, bool beat);

    // 找到连对或者顺子
    QVector<Cards> getSepPairOrSeqSingle(CardInfo& info);
    // 找到基础的三张连对
    Cards getBaseSeqPair(Card::CardPoint point);
    // 找到基础的五张顺子
    Cards getBaseSeqSingle(Card::CardPoint point);
    // 找到炸弹
    QVector<Cards> getBomb(Card::CardPoint beginPoint);

private:
    Player* m_player;
    Cards m_cards;
};



#endif // STRATEGY_H
